package com.manli.api.util;

import com.alibaba.fastjson.JSONObject;
import com.manli.wechat.utils.WeChat;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class WeChatOverUtil {
    @Autowired
    private RedisUtil redisUtil;

    /**
     * accesstoken等信息只缓存1小时,加锁防止高并发，重复初始化token和ticket
     * @return
     */
    public synchronized boolean init(WeChat weChat)throws Exception{
        log.info("微信" + weChat.getAPP_ID() + "开始access_token,jsapiticket初始化.");
        //access_token初始化，不存在则获取，存在则直接用
        if(redisUtil.get(weChat.getAPP_ID() + "_access_token") == null){
            log.info("access_token不存在，开始加锁：" + weChat.getAPP_ID() + "_access_token");
            //加锁
            redisUtil.set(weChat.getAPP_ID() + "_access_token","1",4);
            log.info("access_token加锁成功,为时4秒：" + weChat.getAPP_ID() + "_access_token");
            //需要重新获取
            JSONObject json = weChat.getAccessToken();
            if(json.get("access_token") != null){
                log.info("获取微信access_token成功");
                if(redisUtil.set(weChat.getAPP_ID() + "_access_token",json.getString("access_token"),3600)){
                    log.info("access_token存放redis成功");
                }
            }else{
                redisUtil.del(weChat.getAPP_ID() + "_access_token");
                throw new RuntimeException(weChat.getAPP_ID() + "获取access_token失败！返回：" + json);
            }
        }else{
            log.info("access_token存在，判断是否加锁");
            if(redisUtil.get(weChat.getAPP_ID() + "_access_token").toString().equals("1")){
                log.info(weChat.getAPP_ID() + "_access_token" + "已加锁");
                int flag = 0;
                while (true){
                    Thread.sleep(1000);
                    flag++;
                    log.info("开始每秒循环判断access_token是否已经解锁");
                    if(!redisUtil.get(weChat.getAPP_ID() + "_access_token").toString().equals("1")){
                        log.info(weChat.getAPP_ID() + "_access_token" + "已解锁");
                        break;
                    }
                    if(flag > 4){
                        //保险丝措施防止无限循环
                        break;
                    }
                }
            }
            log.info(weChat.getAPP_ID() + "_access_token" + "未加锁，且已存在");
        }
        //jsapi_ticket初始化，不存在则获取，存在则直接用
        if(redisUtil.get(weChat.getAPP_ID() + "_jsapi_ticket") == null){
            log.info("_jsapi_ticket不存在，开始加锁：" + weChat.getAPP_ID() + "_jsapi_ticket");
            //加锁
            redisUtil.set(weChat.getAPP_ID() + "_jsapi_ticket","1",4);
            log.info("jsapi_ticket加锁成功,为时4秒：" + weChat.getAPP_ID() + "_jsapi_ticket");
            //需要重新获取
            JSONObject json = weChat.getJsapiTicket(getAccessToken(weChat));
            if(json.get("ticket") != null){
                log.info("获取微信jsapi_ticket成功");
                if(redisUtil.set(weChat.getAPP_ID() + "_jsapi_ticket",json.getString("ticket"),3600)){
                    log.info("jsapi_ticket存放redis成功");
                }
            }else{
                redisUtil.del(weChat.getAPP_ID() + "_jsapi_ticket");
                throw new RuntimeException(weChat.getAPP_ID() + "获取jsapi_ticket失败！返回：" + json);
            }
        }else{
            log.info("jsapi_ticket存在，判断是否加锁");
            if(redisUtil.get(weChat.getAPP_ID() + "_jsapi_ticket").toString().equals("1")){
                log.info(weChat.getAPP_ID() + "_jsapi_ticket" + "已加锁");
                int flag = 0;
                while (true){
                    Thread.sleep(1000);
                    flag++;
                    log.info("开始每秒循环判断jsapi_ticket是否已经解锁");
                    if(!redisUtil.get(weChat.getAPP_ID() + "_jsapi_ticket").toString().equals("1")){
                        log.info(weChat.getAPP_ID() + "_jsapi_ticket" + "已解锁");
                        break;
                    }
                    if(flag > 4){
                        //保险丝措施防止无限循环
                        break;
                    }
                }
            }
            log.info(weChat.getAPP_ID() + "_jsapi_ticket" + "未加锁，且已存在");
        }

        //卡券api_ticket初始化，不存在则获取，存在则直接用
        if(redisUtil.get(weChat.getAPP_ID() + "_cardapi_ticket") == null){
            log.info("_cardapi_ticket不存在，开始加锁：" + weChat.getAPP_ID() + "_cardapi_ticket");
            //加锁
            redisUtil.set(weChat.getAPP_ID() + "_cardapi_ticket","1",4);
            log.info("_cardapi_ticket加锁成功,为时4秒：" + weChat.getAPP_ID() + "_cardapi_ticket");
            //需要重新获取
            JSONObject json = weChat.getWxCardApiTicket(getAccessToken(weChat));
            if(json.get("ticket") != null){
                log.info("获取微信_cardapi_ticket成功");
                if(redisUtil.set(weChat.getAPP_ID() + "_cardapi_ticket",json.getString("ticket"),3600)){
                    log.info("_cardapi_ticket存放redis成功");
                }
            }else{
                redisUtil.del(weChat.getAPP_ID() + "_cardapi_ticket");
                throw new RuntimeException(weChat.getAPP_ID() + "获取_cardapi_ticket失败！返回：" + json);
            }
        }else{
            log.info("_cardapi_ticket存在，判断是否加锁");
            if(redisUtil.get(weChat.getAPP_ID() + "_cardapi_ticket").toString().equals("1")){
                log.info(weChat.getAPP_ID() + "_cardapi_ticket" + "已加锁");
                int flag = 0;
                while (true){
                    Thread.sleep(1000);
                    flag++;
                    log.info("开始每秒循环判断_cardapi_ticket是否已经解锁");
                    if(!redisUtil.get(weChat.getAPP_ID() + "_cardapi_ticket").toString().equals("1")){
                        log.info(weChat.getAPP_ID() + "_cardapi_ticket" + "已解锁");
                        break;
                    }
                    if(flag > 4){
                        //保险丝措施防止无限循环
                        break;
                    }
                }
            }
            log.info(weChat.getAPP_ID() + "_cardapi_ticket" + "未加锁，且已存在");
        }

        return true;
    }

    /**
     * 获取accesstoken
     * @return
     */
    public String getAccessToken(WeChat weChat)throws Exception{
        weChat.isInited();
        if(redisUtil.get(weChat.getAPP_ID() + "_access_token") == null){
            init(weChat);
            return redisUtil.get(weChat.getAPP_ID() + "_access_token").toString();
        }else{
            return redisUtil.get(weChat.getAPP_ID() + "_access_token").toString();
        }
    }

    /**
     * 获取jsapiticket
     * @return
     */
    public String getJsapiTicket(WeChat weChat)throws Exception{
        weChat.isInited();
        if(redisUtil.get(weChat.getAPP_ID() + "_jsapi_ticket") == null){
            init(weChat);
            return redisUtil.get(weChat.getAPP_ID() + "_jsapi_ticket").toString();
        }else{
            return redisUtil.get(weChat.getAPP_ID() + "_jsapi_ticket").toString();
        }
    }

    /**
     * 获取卡券cardapiticket
     * @return
     */
    public String getCardApiTicket(WeChat weChat)throws Exception{
        weChat.isInited();
        if(redisUtil.get(weChat.getAPP_ID() + "_cardapi_ticket") == null){
            init(weChat);
            return redisUtil.get(weChat.getAPP_ID() + "_cardapi_ticket").toString();
        }else{
            return redisUtil.get(weChat.getAPP_ID() + "_cardapi_ticket").toString();
        }
    }

}
